package com.ingenico.insider.nodes;

import java.awt.Color;
import java.awt.Font;
import java.awt.Paint;
import java.awt.geom.Rectangle2D;
import java.awt.geom.RoundRectangle2D;

import edu.umd.cs.piccolo.activities.PInterpolatingActivity;
import edu.umd.cs.piccolo.nodes.PPath;
import edu.umd.cs.piccolo.nodes.PText;

public class PNotificationArea extends PPath {
	/**
	 * Generated Serial Version UID
	 */
	private static final long serialVersionUID = -8813885450577629627L;

	private static final double MARGIN_LEFT = 10;
	private static final double MARGIN_RIGHT = 10;
	private static final double MARGIN_TOP = 3;
	private static final double MARGIN_BOTTOM = 3;
	private static final double MARGIN_BAR = 2;
	private static final double ARC_DIAMETER = 20;

	/**
	 * A round rectangle shape used to draw the background
	 */
	private final RoundRectangle2D bgRectangle;
	
	/**
	 * The child PPath object that contains the progress bar background...
	 */
	private final PPath progressBar;
	
	/**
	 * The child PPath object that contains the progress bar foreground (display)...
	 */
	private final PPath progressBarDisplay;
	
	/**
	 * The child PTex object that contains the user (notification) text... 
	 */
	private final PText userText;

	/**
	 * An interpolating activity that is used to animate the box when it disappears...
	 */
	private PInterpolatingActivity disappearanceActivity;

	/**
	 * The default transparency of the box
	 * 
	 * This is the nominal transparency. The actual transparency may vary when the
	 * disappearanceActivity is hiding the notification box...
	 */
	private float defaultTransparency = 1f;

	/**
	 * The disapearance animation duration in ms
	 */
	private long disappearanceDuration = 1500;

	/**
	 * The minimal width when progress bar is visible...
	 */
	private double minWidth = 100;

	/**
	 * The progressBar height... 
	 */
	private double barHeight = 10;

	private void updateBackground() {
		final double textWidth = userText.getWidth();
		final double textHeight = userText.getHeight();

		double bgWidth;
		double bgHeight;

		bgHeight = textHeight;
		if ( (textWidth < minWidth) && (getProgressBarVisible()) ){
			bgWidth = minWidth;
		} else {
			bgWidth = textWidth;
		}

		if (getProgressBarVisible()) {
			Rectangle2D.Double progrectBG = new Rectangle2D.Double(MARGIN_LEFT, MARGIN_TOP + textHeight + MARGIN_BAR, bgWidth, barHeight);
			progressBar.setPathTo(progrectBG);
			bgHeight += MARGIN_BAR + barHeight;
		}

		bgHeight += MARGIN_TOP + MARGIN_BOTTOM;
		bgWidth += MARGIN_LEFT + MARGIN_RIGHT;

		bgRectangle.setRoundRect(0, 0, bgWidth, bgHeight, ARC_DIAMETER, ARC_DIAMETER);

		this.setPathTo(bgRectangle);
	}

	public PNotificationArea (String displayedText, boolean progressBarVisible) {
//		synchronized (disappearanceActivity) {
			disappearanceActivity = null;
//		}
		bgRectangle = new RoundRectangle2D.Float();
		userText = new PText();
		userText.translate(MARGIN_LEFT, MARGIN_TOP);
		userText.setTextPaint(Color.WHITE);
		userText.setFont(new Font(null, Font.ITALIC | Font.BOLD, 12));
		userText.setPickable(false);
		addChild(userText);

		progressBar = new PPath();
//		progressBar.setPaint(new Color(0,80,0));
		progressBar.setPickable(false);
		addChild(progressBar);

		progressBarDisplay = new PPath();
//		progressBarDisplay.setPaint(Color.GREEN);
		progressBarDisplay.setPickable(false);
		progressBar.addChild(progressBarDisplay);

		setUserText(displayedText);
		updateBackground();

		setProgressBarVisible(progressBarVisible);
		super.setVisible(progressBarVisible);
	}

	public float getDefaultTransparency() {
		return defaultTransparency;
	}

	public void setDefaultTransparency(float defaultTransparency) {
		this.defaultTransparency = defaultTransparency;
	}

	public Paint getTextPaint() {
		return userText.getPaint();
	}

	public void setTextPaint(Paint textPaint) {
		userText.setPaint(textPaint);
	}

	public Paint getProgressBackgroundPaint() {
		return progressBar.getPaint();
	}

	public void setProgressBackgroundPaint(Paint progressBackgroundPaint) {
		progressBar.setPaint(progressBackgroundPaint);
	}

	public Paint getProgressDisplayPaint() {
		return progressBarDisplay.getPaint();
	}

	public void setProgressDisplayPaint(Paint progressDisplayPaint) {
		progressBarDisplay.setPaint(progressDisplayPaint);
	}

	public long getDisappearanceDuration() {
		return disappearanceDuration;
	}

	public void setDisappearanceDuration(long disappearanceDuration) {
		this.disappearanceDuration = disappearanceDuration;
	}

	public void setUserText(String displayedText) {
		userText.setText(displayedText);
		updateBackground();
	}

	public String getUserText() {
		return userText.getText();
	}

	public void setProgressBar(float value) {
		if (value >= 1) {
			setProgressBarVisible(false);
		} else {
			final Rectangle2D progressBackgroundBounds = progressBar.getPathReference().getBounds();
			Rectangle2D.Double progrect = new Rectangle2D.Double(progressBackgroundBounds.getX(), progressBackgroundBounds.getY(), progressBackgroundBounds.getWidth() * value, barHeight);
			progressBarDisplay.setPathTo(progrect);
			setProgressBarVisible(true);
		}
	}

	public void setProgressBarVisible(boolean visible) {
//		if ( (visible==true) && ( ! getProgressBarVisible()) ) {
//			userText.translate(-3, -7);
//		} else if ( (visible==false) && ( getProgressBarVisible()) ) {
//			userText.translate(3, 7);
//		}
		updateBackground();
		progressBar.setVisible(visible);
	}

	public boolean getProgressBarVisible() {
		return progressBar.getVisible();
	}

	@Override
	public void setVisible(boolean visible) {
		if (visible) {
//			synchronized (disappearanceActivity) {
				if ( (disappearanceActivity != null) && disappearanceActivity.isStepping() ) {
					disappearanceActivity.terminate();
					disappearanceActivity = null;
				}
//			}
			setTransparency(defaultTransparency);
			super.setVisible(true);
		} else {
			if (getTransparency() == 0) {
				super.setVisible(false);
			}
			if ( (disappearanceActivity == null) || ( ! disappearanceActivity.isStepping()) ) {
				if (disappearanceActivity != null) {
					disappearanceActivity.terminate();
				}
				// PInterpolatingActivity(duration, rate)
				disappearanceActivity = new PInterpolatingActivity(disappearanceDuration, 50) {
					private float source;
	
					protected void activityStarted() {
						source = defaultTransparency;
						super.activityStarted();
					}

					public void setRelativeTargetValue(float zeroToOne) {
						setTransparency(source + (zeroToOne * (0 - source)));
					}							
				};
				addActivity(disappearanceActivity);
			}
		}
	}
}
